﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Drawing;

namespace Atechnology.glassCAD.Shapes.CutViewer
{
    public class CodrExpression
    {
        private Size size;
        public Size Size
        {
            get { return size; }
            set { size = value; }
        }

        private string s;
        public string S
        {
            get { return s; }
            set { s = value; }
        }

        private int r;
        public int R
        {
            get { return r; }
            set { r = value; }
        }
    }

    public class CodrParser
    {
        private string sizesText;

        public string ParseCodr(string fileName)
        {
            Stream stream = File.Open(fileName, FileMode.Open);
            string result = this.ParseCodr(stream);
            stream.Close();
            return result;
        }

        public string ParseCodr(Stream stream)
        {
            sizesText = "Codr sizes: \r\n";
            while (SeekNextExpression(stream))
                AddExpressionToSizesText(this.ReadExpression(stream));
            return sizesText;
        }

        private int ReadL(Stream stream)
        {
            string l = "";
            StringBuilder builderL = new StringBuilder(l);
            int symbol = stream.ReadByte();
            while ((char)symbol != 'H')
            {
                builderL.Append((char)symbol);
                symbol = stream.ReadByte();
                while (symbol == 13 || symbol == 10)
                    symbol = stream.ReadByte();
            }
            return int.Parse(builderL.ToString());
        }

        private int ReadH(Stream stream)
        {
            string h = "";
            StringBuilder builderH = new StringBuilder(h);
            int symbol = stream.ReadByte();
            while ((char)symbol != 'R')
            {
                builderH.Append((char)symbol);
                symbol = stream.ReadByte();
                while (symbol == 13 || symbol == 10)
                    symbol = stream.ReadByte();
            }
            return int.Parse(builderH.ToString());
        }

        private int ReadP(Stream stream)
        {
            string p = "";
            StringBuilder builderP = new StringBuilder(p);
            int symbol = stream.ReadByte();
            while ((char)symbol != 'L')
            {
                builderP.Append((char)symbol);
                symbol = stream.ReadByte();
                while (symbol == 13 || symbol == 10)
                    symbol = stream.ReadByte();                    
            }
            return int.Parse(builderP.ToString());
        }

        private int ReadR(Stream stream)
        {
            string r = "";
            StringBuilder builderR = new StringBuilder(r);
            int symbol = stream.ReadByte();
            while ((char)symbol != 'S')
            {
                builderR.Append((char)symbol);
                symbol = stream.ReadByte();
                while (symbol == 13 || symbol == 10)
                    symbol = stream.ReadByte();
            }
            return int.Parse(builderR.ToString());
        }

        private string ReadS(Stream stream)
        {
            string s = "";
            StringBuilder builderS = new StringBuilder(s);

            int symbol = 'S';
            while ((char)symbol != 'P')
            {
                if ((char)symbol == ')')
                {
                    stream.Position = stream.Position - 1;
                    return builderS.ToString();
                }
                builderS.Append((char)symbol);
                symbol = stream.ReadByte();
            }
            return builderS.ToString();
        }       

        private CodrExpression ReadExpression(Stream stream)
        {
            int p = this.ReadP(stream);
            int l = this.ReadL(stream);
            int h = this.ReadH(stream);
            int r = this.ReadR(stream);
            string s = this.ReadS(stream);

            Size size = new Size(l, h);
            CodrExpression expr = new CodrExpression();
            expr.Size = size;
            expr.S = s;
            expr.R = r;
            return expr;            
        }

        private bool SeekToSymbol(Stream stream, char symbol)
        {
            int _symbol = stream.ReadByte();
            while ((char)_symbol != symbol)
            {
                if ((char)_symbol == ')')
                    return false;
                _symbol = stream.ReadByte();
            }
            return true;
        }

        private bool SeekNextExpression(Stream stream)
        {
            if(stream.Position != 0)
                stream.Position = stream.Position - 1;
            int symbol = stream.ReadByte();            
            while ((char)symbol != 'P')
            {
                if ((char)symbol == ')')
                    return false;
                if ((char)symbol == 'E')
                    throw new Exception();
                symbol = stream.ReadByte();
            }
            return true;
        }

        private void AddExpressionToSizesText(CodrExpression expr)
        {
            sizesText += expr.Size.Width.ToString() + " " + expr.Size.Height.ToString() + " " + "R" + expr.R.ToString() + " " + expr.S + "\r\n";
        }
    }
}
